home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1995 November / EnigmA AMIGA RUN 02 (1995)(G.R. Edizioni)(IT)[!][issue 1995-11][Skylink CD].iso / earcd / unix / mp14tar.z / mp14tar / mpack / unixos.c < prev    next >
C/C++ Source or Header  |  1994-06-01  |  6KB  |  263 lines

  1. /* (C) Copyright 1993 by John G. Myers
  2.  * All Rights Reserved.
  3.  *
  4.  * Permission to use, copy, modify, distribute, and sell this software
  5.  * and its documentation for any purpose is hereby granted without
  6.  * fee, provided that the above copyright notice appear in all copies
  7.  * and that both that copyright notice and this permission notice
  8.  * appear in supporting documentation, and that the name of John G.
  9.  * Myers not be used in advertising or publicity pertaining to
  10.  * distribution of the software without specific, written prior
  11.  * permission.  John G. Myers makes no representations about the
  12.  * suitability of this software for any purpose.  It is provided "as
  13.  * is" without express or implied warranty.
  14.  *
  15.  * JOHN G. MYERS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
  16.  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  17.  * FITNESS, IN NO EVENT SHALL JOHN G. MYERS BE LIABLE FOR ANY SPECIAL,
  18.  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
  19.  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  20.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
  21.  * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22.  */
  23. #include <stdio.h>
  24. #include <ctype.h>
  25. #include <string.h>
  26. #include <errno.h>
  27. #include <sys/types.h>
  28. #include <sys/param.h>
  29. #include <netdb.h>
  30. #include "xmalloc.h"
  31. #include "common.h"
  32.  
  33. #ifndef MAXHOSTNAMELEN
  34. #define MAXHOSTNAMELEN 64
  35. #endif
  36.  
  37. extern int errno;
  38. extern char *malloc();
  39. extern char *getenv();
  40.  
  41. int overwrite_files = 0;
  42. int didchat;
  43.  
  44. /* The name of the file we're writing */
  45. static char *output_fname = 0;
  46.  
  47. /* Characters that shouldn't be in filenames */
  48. #define BADCHARS "!$&*()|\'\";<>[]{}?/`\\ \t"
  49.  
  50. /* Generate a message-id */
  51. char *os_genid()
  52. {
  53.     static int pid = 0;
  54.     static time_t curtime;
  55.     static char hostname[MAXHOSTNAMELEN+1];
  56.     char *result;
  57.     struct hostent *hp;
  58.     
  59.  
  60.     if (pid == 0) {
  61.     pid = getpid();
  62.     time(&curtime);
  63.     gethostname(hostname, sizeof(hostname));
  64.  
  65.     /* If we don't have a FQDN, try canonicalizing with gethostbyname */
  66.     if (!strchr(hostname, '.')) {
  67.         hp = gethostbyname(hostname);
  68.         if (hp) {
  69.         strcpy(hostname, hp->h_name);
  70.         }
  71.     }
  72.     }
  73.  
  74.     result = malloc(25+strlen(hostname));
  75.     sprintf(result, "%d.%d@%s", pid, curtime++, hostname);
  76.     return result;
  77. }
  78.  
  79. /* Create and return directory for a message-id */
  80. char *os_idtodir(id)
  81. char *id;
  82. {
  83.     static char buf[4096];
  84.     char *p;
  85.  
  86.     if (getenv("TMPDIR")) {
  87.     strcpy(buf, getenv("TMPDIR"));
  88.     }
  89.     else {
  90.     strcpy(buf, "/tmp");
  91.     }
  92.     strcat(buf, "/m-prts-");
  93.     p = getenv("USER");
  94.     if (!p) p = getenv("LOGNAME");
  95.     if (!p) p = "x";
  96.     strcat(buf, p);
  97.     
  98.     (void)mkdir(buf, 0700);
  99.  
  100.     p = buf + strlen(buf);
  101.     *p++ = '/';
  102.     while (*id && p < buf+sizeof(buf)-10 ) {
  103.     if (isprint(*id) && !strchr(BADCHARS, *id)) *p++ = *id;
  104.     id++;
  105.     }
  106.     *p = '\0';
  107.     if (mkdir(buf, 0700) == -1 && errno != EEXIST) {
  108.     perror(buf);
  109.     return 0;
  110.     }
  111.     *p++ = '/';
  112.     *p = '\0';
  113.     return buf;
  114. }
  115.  
  116. /*
  117.  * We are done with the directory returned by os_idtodir()
  118.  * Remove it
  119.  */
  120. os_donewithdir(dir)
  121. char *dir;
  122. {
  123.     char *p;
  124.  
  125.     /* Remove trailing slash */
  126.     p = dir + strlen(dir) - 1;
  127.     *p = '\0';
  128.  
  129.     rmdir(dir);
  130. }
  131.  
  132. /*
  133.  * Create a new file, with suggested filename "fname".
  134.  * "fname" may have come from an insecure source, so clean it up first.
  135.  * It may also be null.
  136.  * "contentType" is passed in for use by systems that have typed filesystems.
  137.  * "flags" contains a bit pattern describing attributes of the new file.
  138.  */
  139. FILE *os_newtypedfile(fname, contentType, flags)
  140. char *fname;
  141. char *contentType;
  142. int flags;
  143. {
  144.     char *p;
  145.     static int filesuffix=0;
  146.     char buf[128], *descfname=0;
  147.     FILE *outfile = 0;
  148.  
  149.     if (!fname) fname = "";
  150.  
  151.     /* If absolute path name, chop to tail */
  152.     if (*fname == '/') {
  153.     p = strrchr(fname, '/');
  154.     fname = p+1;
  155.     }
  156.  
  157.     /* Get rid of leading ~ or ~/ */
  158.     while (*fname == '~' || *fname == '/') fname++;
  159.     
  160.     /* Clean out bad characters, create directories along path */
  161.     for (p=fname; *p; p++) {
  162.     if (*p == '/') {
  163.         if (!strncmp(p, "/../", 4)) {
  164.         p[1] = p[2] = 'X';
  165.         }
  166.         *p = '\0';
  167.         (void) mkdir(fname, 0777);
  168.         *p = '/';
  169.     }
  170.     else if (!isprint(*p) || strchr(BADCHARS, *p)) *p = 'X';
  171.     }
  172.  
  173.     if (!fname[0]) {
  174.     do {
  175.         if (outfile) fclose(outfile);
  176.         sprintf(buf, "part%d", ++filesuffix);
  177.     } while (outfile = fopen(buf, "r"));
  178.     fname = buf;
  179.     }
  180.     else if (!overwrite_files && (outfile = fopen(fname, "r"))) {
  181.     do {
  182.         fclose(outfile);
  183.         sprintf(buf, "%s.%d", fname, ++filesuffix);
  184.      
  185.     } while (outfile = fopen(buf, "r"));
  186.     fname = buf;
  187.     }
  188.  
  189.     outfile = fopen(fname, "w");
  190.     if (!outfile) {
  191.     perror(fname);
  192.     }
  193.  
  194.     if (output_fname) free(output_fname);
  195.     output_fname = strsave(fname);
  196.  
  197.     if (strlen(fname) > sizeof(buf)-6) {
  198.     descfname = xmalloc(strlen(fname)+6);
  199.     }
  200.     else {
  201.     descfname = buf;
  202.     }
  203.     strcpy(descfname, fname);
  204.  
  205.     p = strchr(descfname, '/');
  206.     if (!p) p = descfname;
  207.     if (p = strrchr(p, '.')) *p = '\0';
  208.  
  209.     strcat(descfname, ".desc");
  210.     (void) rename(TEMPFILENAME, descfname);
  211.     if (descfname != buf) free(descfname);
  212.     
  213.     fprintf(stdout, "%s (%s)\n", output_fname, contentType);
  214.     didchat = 1;
  215.  
  216.     return outfile;
  217. }
  218.  
  219. /*
  220.  * Close a file opened by os_newTypedFile()
  221.  */
  222. os_closetypedfile(outfile)
  223. FILE *outfile;
  224. {
  225.     fclose(outfile);
  226. }
  227.  
  228. /*
  229.  * (Don't) Handle a BinHex'ed file
  230.  */
  231. int
  232. os_binhex(infile, part, nparts)
  233. FILE *infile;
  234. int part;
  235. int nparts;
  236. {
  237.     return 1;
  238. }
  239.  
  240. /*
  241.  * Warn user that the MD5 digest of the last file created by os_newtypedfile()
  242.  * did not match that supplied in the Content-MD5: header.
  243.  */
  244. os_warnMD5mismatch()
  245. {
  246.     char *warning;
  247.  
  248.     warning = xmalloc(strlen(output_fname) + 100);
  249.     sprintf(warning, "%s was corrupted in transit",
  250.         output_fname);
  251.     warn(warning);
  252.     free(warning);
  253. }
  254.  
  255. /*
  256.  * Report an error (in errno) concerning a filename
  257.  */
  258. os_perror(file)
  259. char *file;
  260. {
  261.     perror(file);
  262. }
  263.